package org.charles.zhifou.common.enums;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonStreamContext;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * <h1>RequestBody 中的枚举类型映射转换器</h1>
 *
 * @author charles
 * @version 1.0
 */
@Component
@Slf4j
public class CodeToEnumDeserializer extends JsonDeserializer<BaseEnum> {
    @Override
    public BaseEnum deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
            throws IOException {
        // 先转为 String, 判断是否为空, 如果为空, 则返回 null
        final String codeString = jsonParser.getValueAsString();
        if (StringUtils.isBlank(codeString)) {
            return null;
        }
        final Integer code = Integer.parseInt(codeString);

        final JsonStreamContext parsingContext = jsonParser.getParsingContext();
        final String currentName = parsingContext.getCurrentName();
        final Object currentValue = parsingContext.getCurrentValue();
        try {
            final Field declaredField = currentValue.getClass().getDeclaredField(currentName);
            final Class<?> targetType = declaredField.getType();
            final Method valuesMethod = targetType.getDeclaredMethod("values");
            BaseEnum[] enums = (BaseEnum[]) valuesMethod.invoke(null);
            for (BaseEnum anEnum : enums) {
                if(anEnum.getCode().equals(code)){
                    return anEnum;
                }
            }
            throw new RuntimeException(declaredField.getName() + " 属性未找到对应的枚举类对象");
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | NoSuchFieldException e) {
            throw new RuntimeException("请求体 Enum 转换发生错误", e);
        }
    }
}
